function varargout = TLCriticalsectionDlg(action,varargin)

% TL_CRITICALSECTION_DLG manages the user interface of TargetLink Critical Section block
%
% SYNTAX dlgInfo = TLCriticalsectionDlg('GetDlgInfo');
%   gets dialog info of TargetLink Critical Section block
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLCriticalsectionDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLCriticalsectionDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLCriticalsectionDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLCriticalsectionDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLCriticalsectionDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLCriticalsectionDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/MultirateBlockset/MultirateBlockset_UI/Sources/MSrc/project.pj $
% $Revision: 1.8 $
% $Date: 2011/03/18 07:21:44MEZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('rtos');
        titleName = 'Critical Section';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'Critical Section'};
        dlgInfo.bDateLabel      = 0;
        dlgInfo.bPlotSignal     = 0;
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);

    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName
            case 'Critical Section'
                [sheetDims, ctrlPos] = FcnCalcCriticalSectionControlPositions(commonGeom);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'Create',
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = strmatch(pageName, dlgdata.pageNames, 'exact');
        switch pageName
            case 'Critical Section'
                dlgdata = FcnCreateCriticalSectionControls(pageNum,dlgfig,dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;

    case 'Manage',
        pageName   = varargin{1};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = strmatch(pageName,dlgdata.pageNames,'exact');
        switch pageName
            case 'Critical Section'
                [dlgdata, bModified] = ...
                    FcnManageCriticalSectionControls(pageNum,dlgdata,pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'Update'
        dlgfig    = varargin{1};
        dlgdata   = varargin{2};
        pageNum   = varargin{3};

        pageName  = dlgdata.pageNames{pageNum};
        switch pageName
            case 'Critical Section'
                dlgdata = FcnUpdateCriticalSectionControls(dlgdata,dlgfig,pageNum);
        end
        varargout{1} = dlgdata;

    case 'Apply'
        dlgdata = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;

    otherwise
        error(['Invalid action: "' action '"']);
end


%------------------------------------------------------------------------------
% FcnCreateCriticalSectionControls creates critical section page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%------------------------------------------------------------------------------
function dlgdata = FcnCreateCriticalSectionControls(pageNum,dlgfig,dlgdata)

Children = dlgdata.pageData{pageNum}.children;
ctrlPos  = dlgdata.pageData{pageNum}.ctrlPos;

bgColor = 'w';
% overwrite colors in stand alone mode
if ~dlgdata.bIsFullVs
    bgColor = get(dlgfig,'Color');
end; %if

% create the protection mechanism groupbox
Children.protMechGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Protection mechanism'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.protMechGroupbox);

%---------------------------------------
% description controls
%---------------------------------------
Children.descriptionLabel = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Style',              'text', ...
    'String',             'Description:', ...
    'Position',           ctrlPos.descriptionLabel);

Children.descriptionEdit = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Enable',             flag2str(dlgdata.bIsFullVs), ...
    'BackgroundColor',    bgColor, ...
    'Style',              'edit', ...
    'Position',           ctrlPos.descriptionEdit);

%---------------------------------------
% protection mechanism controls
%---------------------------------------
Children.protMechanismLabel = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Style',              'text', ...
    'String',             'Protection mechanism:', ...
    'Position',           ctrlPos.protMechanismLabel);

Children.protMechanismEdit = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Enable',             flag2str(dlgdata.bIsFullVs), ...
    'BackgroundColor',    bgColor, ...
    'Style',              'edit', ...
    'Position',           ctrlPos.protMechanismEdit);

Children.protMechanismButton = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Enable',             flag2str(dlgdata.bIsFullVs), ...
    'Style',              'pushbutton', ...
    'String',             ' . . . ', ...
    'Position',           ctrlPos.protMechanismButton);

%---------------------------------------
% kind controls
%---------------------------------------
Children.kindLabel = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Style',              'text', ...
    'String',             'Kind:', ...
    'Position',           ctrlPos.kindLabel);

Children.kindEdit = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'enable',             'off', ...
    'Style',              'edit', ...
    'String',             'DEFAULT', ...
    'Position',           ctrlPos.kindEdit);

%---------------------------------------
% parameter list controls
%---------------------------------------
Children.parameterListLabel = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Style',              'text', ...
    'String',             'Parameter list:', ...
    'Position',           ctrlPos.parameterListLabel);

Children.parameterListEdit = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'enable',             'off', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.parameterListEdit);

%---------------------------------------
% resource controls
%---------------------------------------
Children.resourceLabel = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'Style',              'text', ...
    'String',             'Resource:', ...
    'Position',           ctrlPos.resourceLabel);

Children.resourceEdit = uicontrol( ...
    'Parent',             Children.protMechGroupbox, ...
    'enable',             'off', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.resourceEdit);

dlgdata.pageData{pageNum}.children = Children;
dlgdata = FcnUpdateCriticalSectionControls(dlgdata,dlgfig,pageNum);


%------------------------------------------------------------------------------
% FcnManageCriticalSectionControls manages critical section page callbacks
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageCriticalSectionControls(pageNum,dlgdata,pageAction)

bModified  = 0;
Children   = dlgdata.pageData{pageNum}.children;

switch pageAction
    case 'descriptionEdit'
        dlgdata.data.description = get(Children.descriptionEdit,'String');
        bModified = 1;
    case 'protMechanismEdit'
        dlgdata.data.protection = get(Children.protMechanismEdit,'String');
        bModified = 1;
    case 'protMechanismButton'
        protMech = dsdd( 'SelectObject', ...
            'CurrentPath',       dlgdata.data.protection, ...
            'ObjectKind',        'ProtectionMechanism');
        if ~isempty(protMech)
            dlgdata.data.protection = protMech;
            bModified = 1;
        end
    otherwise
        error(['Invalid control ' pageAction]);
end


%------------------------------------------------------------------------------
% FcnCalcCriticalSectionControlPositions calculates positions for all ctrls
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnCalcCriticalSectionControlPositions(commonGeom)

strings_and_styles = {...
    'Description:',            'text';...
    'WWWWWWWWWWWWWWWWWWWWWWWW','edit'; ...
    'Protection mechanism:',   'text';...
    'WWWWWWWWWWWWWWWWWWWWWWWW','edit'; ...
    '  . . .  ',               'pushbutton'};

[descriptionLabelSize, ...
    descriptionEditSize, ...
    protMechanismLabelSize, ...
    protMechanismEditSize, ...
    protMechanismButtonSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

widths = [ ...
    protMechanismLabelSize(1), ...
    protMechanismEditSize(1), ...
    protMechanismButtonSize(1)];
[col,colWidth,colDelta,rowDelta] = ds_get_gui_columns(widths,commonGeom); %#ok

cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + ...
    commonGeom.sheetBottomEdgeBuffer;
protMechGroupboxWidth = col(end) + ...
    colWidth(end) + ...
    commonGeom.frameSideEdgeBuffer;

protMechGroupboxHeight = ...
    commonGeom.frameTopEdgeBuffer + ...
    4 * rowDelta + ...
    5 * commonGeom.editHeight + ...
    commonGeom.frameBottomEdgeBuffer;
ctrlPos.protMechGroupbox =  ...
    [cx cy  protMechGroupboxWidth protMechGroupboxHeight];

% resource label
cx = col(1);
cy = commonGeom.frameBottomEdgeBuffer;
ctrlPos.resourceLabel = [cx cy protMechanismLabelSize];

% resource edit
cx = col(2);
ctrlPos.resourceEdit = [cx cy protMechanismEditSize];

% parameter list label
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.parameterListLabel = [cx cy protMechanismLabelSize];

% parameter list edit
cx = col(2);
ctrlPos.parameterListEdit = [cx cy protMechanismEditSize];

% kind label
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.kindLabel = [cx cy protMechanismLabelSize];

% kind edit
cx = col(2);
ctrlPos.kindEdit = [cx cy protMechanismEditSize];

% protection mechanism label
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.protMechanismLabel = [cx cy protMechanismLabelSize];

% protection mechanism edit
cx = col(2);
ctrlPos.protMechanismEdit = [cx cy protMechanismEditSize];

% protection mechanism button
cx = col(3);
ctrlPos.protMechanismButton = [cx cy protMechanismButtonSize];

% description label
cx = col(1);
cy = cy + commonGeom.editHeight + rowDelta;
ctrlPos.descriptionLabel = [cx cy descriptionLabelSize];

% description edit
cx = col(2);
ctrlPos.descriptionEdit = [cx cy descriptionEditSize];

%-----------------------------------------------------------
% calculate overall dimensions
%-----------------------------------------------------------
width = ...
    2*commonGeom.frameSideEdgeBuffer + ...
    protMechGroupboxWidth;

height = ...
    protMechGroupboxHeight + ...
    commonGeom.textHeight + ...
    commonGeom.sheetBottomEdgeBuffer;

sheetDims = [width height];

%------------------------------------------------------------------------------
% FcnUpdateCriticalSectionControls updates the controls of the critical section tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number (=1 for alarm page)
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%------------------------------------------------------------------------------

function dlgdata = FcnUpdateCriticalSectionControls(dlgdata,dlgfig,pageNum) %#ok

Children = dlgdata.pageData{pageNum}.children;

% fill description control
% make string single-line, because edit control can not have multi-line text
description  = strrep(dlgdata.data.description, char(10),' ');
set(Children.descriptionEdit,'String',description);

protMechObjPath = [dsdd('GetDefaultPath','Protectionmechanism') '/' dlgdata.data.protection];
[bExist,hProtection] = dsdd('exist',dlgdata.data.protection, ...
   'Parent',      dsdd('GetDefaultPath','Protectionmechanism'), ...
   'ObjectKind',  'ProtectionMechanism');

% fill protection mechanism control
if isempty(deblank(dlgdata.data.protection))
    set(Children.protMechanismEdit, ...
        'ForeGroundColor','r', ...
        'String','<unspecified>');
elseif ~bExist
    ds_error_msg({'The Protectionmechanism object', protMechObjPath, 'does not exist.'}, ...
        'Title','Data Dictionary object not found');
    set(Children.protMechanismEdit, ...
        'ForeGroundColor','r', ...
        'String',dlgdata.data.protection);
    set(Children.KindEdit, ...
        'String','DEFAULT');
    set(Children.protMechanismEdit, ...
        'String','');
    set(Children.protMechanismEdit, ...
        'String','');
else
    set(Children.protMechanismEdit, ...
        'ForeGroundColor','k', ...
        'String',dlgdata.data.protection);

    % get protection mechanism kind from Data Dictionary
    kind = dsdd('GetKind',hProtection);
    % get argument list
    if strcmp(kind,'GENERIC_USER_DEFINED'),
        parameterList = dsdd('GetGenericArgumentList',hProtection);
    else
        parameterList = '';
    end
    % get resource name
    if strcmp(kind,'RESOURCE_LOCK'),
        resource = dsdd('GetResourceRef',hProtection);
        if isempty(resource),
            % use name template instead empty resource
            resource = dsdd('GetResourceNameTemplate',hProtection);
        end
    else
        resource = '';
    end
    set(Children.kindEdit, ...
        'String',kind);
    set(Children.parameterListEdit, ...
        'String',parameterList);
    set(Children.resourceEdit, ...
        'String',resource);
end
